home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
dylibload
/
symfind.c
< prev
Wrap
C/C++ Source or Header
|
1990-05-01
|
11KB
|
448 lines
/*
* %M% %I% of %G%
* %W%
*/
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA
endcopyright */
# include <sys/types.h>
# include <ar.h>
# include <ranlib.h>
# include <nlist.h>
# include "xr/UIO.h"
# include "xr/BasicTypes.h"
# include "xr/ThreadsMsg.h"
# include "xr/CommandLine.h"
# include "xr/CommandLoop.h"
# include "xr/libsearch.h"
#define USE_SSU_DEFAULT_LIBRARIES 1
#define DCLCLCE XR_CLCallEnv clce \
= (XR_CLCallEnv) XR_GetTopLevelCLCallEnv()
#define IFPRINTMSG if( XR_CLVerbose(XR_VERBOSITY_NORMAL) )
#define IFPRINTERR if( XR_CLVerbose(XR_VERBOSITY_ERROR) )
#define PRINT XR_CLMsg
#define PRINTMSG IFPRINTMSG PRINT
#define PRINTERR IFPRINTERR PRINT
char *XR_malloc();
char *XR_pointerfree_new();
static void XR_lib_close();
char *get_nth_word();
# define LIB_OPEN_no_space -1
# define LIB_OPEN_no_such_library -2
# define LIB_OPEN_file_not_found -3
# define LIB_OPEN_invalid_archive -4
# define LIB_OPEN_no_symdef_in_archive -5
# define LIB_OPEN_stat_failed -6
# define LIB_OPEN_inconsisten_version -7
static struct library *libraryList;
static int libraryListLength;
static int libraryListMaxLength;
static struct {
struct library *libraryList;
int libraryListLength;
int libraryListMaxLength;
} libraryListStack[LIB_LIST_STACK_MAX_DEPTH];
static int libraryListStackDepth;
/*
* clear the library list
*/
static void
XR_lib_clear()
{
if (libraryList == 0) {
libraryListLength = 0;
libraryListMaxLength = 10;
libraryList = (struct library *)
XR_malloc(libraryListMaxLength * sizeof(struct library));
}
XR_lib_close();
libraryListLength = 0;
}
/*
* close all library file descriptors, the library list remains unchanged
*/
static void
XR_lib_close()
{
struct library *p;
for (p = &libraryList[0]; p < &libraryList[libraryListLength]; p++) {
if (p->fildes != -1) {
XR_Close(p->fildes);
p->fildes = -1;
p->ranp = 0;
p->strp = 0;
}
}
}
/*
* set the library list to the default list
*/
static void
XR_lib_default()
{
XR_lib_clear();
# if USE_SSU_DEFAULT_LIBRARIES
libraryList[libraryListLength].libname = "/usr/lib/libpixrect.a";
libraryList[libraryListLength].fildes = -1;
libraryListLength++;
libraryList[libraryListLength].libname = "/usr/lib/libc.a";
libraryList[libraryListLength].fildes = -1;
libraryListLength++;
libraryList[libraryListLength].libname = "/usr/lib/libm.a";
libraryList[libraryListLength].fildes = -1;
libraryListLength++;
# endif
}
/*
* list the libraries on the library list
*/
static void
XR_lib_list()
{
struct library *p;
DCLCLCE;
IFPRINTMSG {
for (p = &libraryList[0]; p < &libraryList[libraryListLength]; p++) {
PRINT "%s ", p->libname);
}
PRINT "\n");
}
}
/*
* append library to end of library list
*/
static void
XR_lib_append(commandString)
char *commandString;
{
char *libname;
struct library *p;
DCLCLCE;
libname = get_nth_word(XR_GetCurrentCommand(), 1);
if (!libname[0]) {
PRINTERR "libappend: argument needed\n");
return;
}
if (libraryListLength >= libraryListMaxLength) {
struct library * newLibraryList = (struct library *) XR_malloc(
2 * libraryListMaxLength * sizeof(struct library) );
(void) bcopy(libraryList, newLibraryList,
libraryListMaxLength * sizeof(struct library));
libraryList = newLibraryList;
libraryListMaxLength *= 2;
}
p = &libraryList[libraryListLength++];
p->libname = libname;
p->fildes = -1;
XR_lib_list();
}
/*
* prepend library to beginning of library list
*/
static void
XR_lib_prepend(commandString)
char *commandString;
{
char *libname;
struct library *p;
DCLCLCE;
libname = get_nth_word(XR_GetCurrentCommand(), 1);
if (!libname[0]) {
PRINTERR "libprepend: argument needed\n");
return;
}
if (libraryListLength >= libraryListMaxLength)
libraryList = (struct library *)XR_realloc(libraryList, libraryListMaxLength *= 2);
for (p = &libraryList[libraryListLength]; p > &libraryList[0]; p--) {
*p = *(p - 1);
}
p->libname = libname;
p->fildes = -1;
libraryListLength++;
XR_lib_list();
}
/*
* push the library list down on the stack of library lists
* the top of the stack is an empty library list
*/
static void
XR_lib_push()
{
int ii;
DCLCLCE;
if ((ii = libraryListStackDepth) >= LIB_LIST_STACK_MAX_DEPTH) {
PRINTERR "libpush: library list overflow\n");
return;
}
libraryListStack[ii].libraryList = libraryList;
libraryListStack[ii].libraryListLength = libraryListLength;
libraryListStack[ii].libraryListMaxLength = libraryListMaxLength;
libraryListStackDepth = ii + 1;
libraryList = 0;
XR_lib_clear();
}
/*
* pop up the stack of library lists
*/
static void
XR_lib_pop()
{
int ii;
DCLCLCE;
if ((ii = libraryListStackDepth) <= 0) {
PRINTERR "libpop: library list underflow\n");
return;
}
XR_lib_close();
--ii;
libraryList = libraryListStack[ii].libraryList;
libraryListStack[ii].libraryList = 0;
libraryListLength = libraryListStack[ii].libraryListLength;
libraryListMaxLength = libraryListStack[ii].libraryListMaxLength;
libraryListStackDepth =ii;
}
/*
* register pcr commands to manipulate the library list
*/
void
XR_lib_init()
{
typedef void (*registeredProc)();
static registeredProc
def = XR_lib_default,
pop = XR_lib_pop,
push = XR_lib_push,
close = XR_lib_close,
prepend = XR_lib_prepend,
append = XR_lib_append,
clear = XR_lib_clear,
list = XR_lib_list;
XR_register("libdefault", &def,
"set library list to the default list", 0);
XR_register("libpop", &pop,
"pop up the stack of library lists", 0);
XR_register("libpush", &push,
"push down the stack of library lists", 0);
XR_register("libclose", &close,
"close all libraries to release file descriptors", 0);
XR_register("libprepend", &prepend,
"prepend the argument to the beginning of the library list", 0);
XR_register("libappend", &append,
"append the argument to the end of the library list", 0);
XR_register("libclear", &clear,
"clear the library list", 0);
XR_register("liblist", &list,
"list the libraries on the library list", 0);
XR_lib_default();
}
# define ok_fread(buf, len, count, fd) \
if (XR_Read((fd), (buf), (len)*(count)) < 0) { \
PRINTERR "read error %d\n", XR_GetErrno()); \
goto Bad; \
}
# define ok_fseek(fd, offset, whence) \
if (XR_LSeek((fd), (offset), (whence)) < 0) { \
PRINTERR "lseek error %d\n", XR_GetErrno()); \
goto Bad; \
}
/*
* open the (ii)th library, return the file descriptor for it.
* return small negative integers for error conditions
* (an error message will already have been printed using xr_printf).
*/
static XR_Fildes
XR_lib_open(ii)
int ii;
{
XR_Fildes fd;
char magicString[SARMAG+1];
struct ar_hdr symdefHeader;
char *symdefName;
struct stat buf;
int retval, size;
char *strp;
struct ranlib *ranp, *ranpMax;
DCLCLCE;
if (ii >= libraryListLength)
return ((XR_Fildes)LIB_OPEN_no_such_library);
if ((fd = libraryList[ii].fildes) == -1) {
if ((fd = XR_Open(libraryList[ii].libname, O_RDONLY)) < 0) {
PRINTERR "XR_lib_open: file not found: %s\n",
libraryList[ii].libname);
return ((XR_Fildes)LIB_OPEN_file_not_found);
}
libraryList[ii].fildes = fd;
ok_fread(magicString, SARMAG, 1, fd);
magicString[SARMAG] = 0;
if (strcmp(magicString, ARMAG)) {
PRINTERR "XR_lib_open: invalid archive: %s\n",
libraryList[ii].libname);
return ((XR_Fildes)LIB_OPEN_invalid_archive);
}
ok_fread(&symdefHeader, sizeof(struct ar_hdr), 1, fd);
symdefName = "__.SYMDEF ";
if (strncmp(symdefHeader.ar_name, symdefName, strlen(symdefName))) {
PRINTERR "XR_lib_open: no symdef in archive: %s\n",
libraryList[ii].libname);
return ((XR_Fildes)LIB_OPEN_no_symdef_in_archive);
}
if ((retval = XR_FStat(fd, &buf)) < 0) {
PRINTERR "XR_lib_open: stat failed: %s\n",
libraryList[ii].libname);
return ((XR_Fildes)LIB_OPEN_stat_failed);
}
if (buf.st_mtime > atoi(symdefHeader.ar_date)) {
PRINTERR "XR_lib_open: inconsisten version: %s\n",
libraryList[ii].libname);
return((XR_Fildes)LIB_OPEN_inconsisten_version);
}
ok_fread(&size, sizeof(int), 1, fd);
libraryList[ii].ranp = ranp = (struct ranlib *)XR_pointerfree_new(size);
if (ranp == 0)
return((XR_Fildes)LIB_OPEN_no_space);
ok_fread(libraryList[ii].ranp, size, 1, fd);
libraryList[ii].ranpMax = ranpMax = (struct ranlib *)( (int)ranp + size );
ok_fread(&size, sizeof(int), 1, fd);
libraryList[ii].strp = strp = XR_pointerfree_new(size);
if (strp == 0) {
PRINTERR "XR_lib_open: no space\n");
return((XR_Fildes)LIB_OPEN_no_space);
}
ok_fread(strp, size, 1, fd);
for (; ranp < ranpMax; ranp++)
ranp->ran_un.ran_name += (long)strp;
}
return (fd);
Bad:
return (-1);
}
/*
* given an undefined symbol, look it up in the library list,
* return true, a file descriptor for the library,
* an offset at which the symbol is defined.
* as additional information return a hint of the type of file the library member is
* and the name of the library.
* return false if symbol is not found in any library in the library list.
*/
bool
XR_lib_symfind(sym, libfd, liboffset, magic, modulename)
char *sym;
XR_Fildes *libfd;
long *liboffset;
long *magic;
char **modulename;
{
int libindex;
XR_Fildes fd;
struct ranlib *ranp, *ranpMax;
struct ar_hdr arHdr;
char *libname, *cp, *cq;
DCLCLCE;
for (libindex = 0; (fd = XR_lib_open(libindex)) != LIB_OPEN_no_such_library; libindex++) {
if (fd < 0)
continue;
ranpMax = libraryList[libindex].ranpMax;
for (ranp = libraryList[libindex].ranp; ranp < ranpMax; ranp++) {
if (strcmp(sym, ranp->ran_un.ran_name) == 0) {
*libfd = fd;
*liboffset = ranp->ran_off + sizeof(struct ar_hdr);
*magic = 0;
ok_fseek(fd, ranp->ran_off, 0);
ok_fread(&arHdr, sizeof(struct ar_hdr), 1, fd);
libname = libraryList[libindex].libname;
cp = *modulename = XR_pointerfree_new(strlen(libname) + sizeof(arHdr.ar_name) + 3);
for (cq = libname; *cq; )
*cp++ = *cq++;
*cp++ = '(';
for (cq = arHdr.ar_name; (*cq != ' ') && (cq < &arHdr.ar_name[sizeof(arHdr.ar_name)]); )
*cp++ = *cq++;
*cp++ = ')';
*cp++ = 0;
return(TRUE);
}
}
}
Bad:
return(FALSE);
}
XR_run_symfind()
{
XR_lib_init();
}
/* LOG:
* Earsh Wed Nov 2 17:45:25 1988
* TJW 3/22/88
* tou Tue Sep 12 15:15:50 1989
* Demers, April 16, 1990 8:09:19 am PDT
*/